From: Carlos Garnacho Date: Fri, 13 Jul 2018 13:04:02 +0000 (+0200) Subject: windowManager: Refactor workspace switching animations X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~929^2~4^2~20 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=e5c95b910d;p=gnome-shell.git windowManager: Refactor workspace switching animations Besides the separation into distinct functions, the stored data has been made able to generically store windows from all surrounding workspaces. All while keeping a special mode to animate between two workspaces (The usual till now), this is the only mode exercised so far. In order to ease animations, all window groups are now children of a common container, which is then animated. --- diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js index 02d5f9029..18f393dda 100644 --- a/js/ui/windowManager.js +++ b/js/ui/windowManager.js @@ -1017,10 +1017,10 @@ var WindowManager = new Lang.Class({ }, _actionSwitchWorkspace(action, direction) { - let workspaceManager = global.workspace_manager; - let activeWorkspace = workspaceManager.get_active_workspace(); - let newWs = activeWorkspace.get_neighbor(direction); - this.actionMoveWorkspace(newWs); + let workspaceManager = global.workspace_manager; + let activeWorkspace = workspaceManager.get_active_workspace(); + let newWs = activeWorkspace.get_neighbor(direction); + this.actionMoveWorkspace(newWs); }, _lookupIndex(windows, metaWindow) { @@ -1700,63 +1700,96 @@ var WindowManager = new Lang.Class({ if (this._switchData == null) return; - // Update stacking of windows in inGroup (aka the workspace we are - // switching to). Windows in outGroup are about to be hidden anyway, - // so we just ignore them here. let windows = global.get_window_actors(); - let sibling = null; + let lastCurSibling = null; + let lastDirSibling = []; for (let i = 0; i < windows.length; i++) { - if (windows[i].get_parent() != this._switchData.inGroup) - continue; + if (windows[i].get_parent() == this._switchData.curGroup) { + this._switchData.curGroup.set_child_above_sibling(windows[i], lastCurSibling); + lastCurSibling = windows[i]; + } else { + for (let dir of Object.values(Meta.MotionDirection)) { + let info = this._switchData.surroundings[dir]; + if (!info || windows[i].get_parent() != info.actor) + continue; - this._switchData.inGroup.set_child_above_sibling(windows[i], sibling); - sibling = windows[i]; - } - }, + let sibling = lastDirSibling[dir]; + if (sibling == undefined) + sibling = null; - _switchWorkspace(shellwm, from, to, direction) { - if (!Main.sessionMode.hasWorkspaces || !this._shouldAnimate()) { - shellwm.completed_switch_workspace(); - return; + info.actor.set_child_above_sibling(windows[i], sibling); + lastDirSibling[dir] = windows[i]; + break; + } + } } + }, - let windows = global.get_window_actors(); - - /* @direction is the direction that the "camera" moves, so the - * screen contents have to move one screen's worth in the - * opposite direction. - */ + _getPositionForDirection(direction) { let xDest = 0, yDest = 0; if (direction == Meta.MotionDirection.UP || direction == Meta.MotionDirection.UP_LEFT || direction == Meta.MotionDirection.UP_RIGHT) - yDest = global.screen_height - Main.panel.actor.height; + yDest = -global.screen_height + Main.panel.actor.height; else if (direction == Meta.MotionDirection.DOWN || direction == Meta.MotionDirection.DOWN_LEFT || direction == Meta.MotionDirection.DOWN_RIGHT) - yDest = -global.screen_height + Main.panel.actor.height; + yDest = global.screen_height - Main.panel.actor.height; if (direction == Meta.MotionDirection.LEFT || direction == Meta.MotionDirection.UP_LEFT || direction == Meta.MotionDirection.DOWN_LEFT) - xDest = global.screen_width; + xDest = -global.screen_width; else if (direction == Meta.MotionDirection.RIGHT || direction == Meta.MotionDirection.UP_RIGHT || direction == Meta.MotionDirection.DOWN_RIGHT) - xDest = -global.screen_width; + xDest = global.screen_width; + + return [xDest, yDest]; + }, + _prepareWorkspaceSwitch(from, to, direction) { + if (this._switchData) + return; + + let wgroup = global.window_group; + let windows = global.get_window_actors(); let switchData = {}; + this._switchData = switchData; - switchData.inGroup = new Clutter.Actor(); - switchData.outGroup = new Clutter.Actor(); + switchData.curGroup = new Clutter.Actor(); switchData.movingWindowBin = new Clutter.Actor(); switchData.windows = []; + switchData.surroundings = {}; + + switchData.container = new Clutter.Actor(); + switchData.container.add_actor(switchData.curGroup); - let wgroup = global.window_group; - wgroup.add_actor(switchData.inGroup); - wgroup.add_actor(switchData.outGroup); wgroup.add_actor(switchData.movingWindowBin); + wgroup.add_actor(switchData.container); + + let workspaceManager = global.workspace_manager; + let curWs = workspaceManager.get_workspace_by_index (from); + + for (let dir of Object.values(Meta.MotionDirection)) { + let ws = curWs.get_neighbor(dir); + if (ws == curWs || (to >= 0 && ws.index() != to)) { + switchData.surroundings[dir] = null; + continue; + } + + let info = { index: ws.index(), + actor: new Clutter.Actor() }; + switchData.surroundings[dir] = info; + switchData.container.add_actor(info.actor); + info.actor.raise_top(); + + let [x, y] = this._getPositionForDirection(dir); + info.actor.set_position(x, y); + } + + switchData.movingWindowBin.raise_top(); for (let i = 0; i < windows.length; i++) { let actor = windows[i]; @@ -1777,20 +1810,65 @@ var WindowManager = new Lang.Class({ actor.reparent(switchData.movingWindowBin); } else if (window.get_workspace().index() == from) { switchData.windows.push(record); - actor.reparent(switchData.outGroup); - } else if (window.get_workspace().index() == to) { - switchData.windows.push(record); - actor.reparent(switchData.inGroup); - actor.show(); + actor.reparent(switchData.curGroup); + } else { + let visible = false; + for (let dir of Object.values(Meta.MotionDirection)) { + let info = switchData.surroundings[dir]; + + if (!info || info.index != window.get_workspace().index()) + continue; + + switchData.windows.push(record); + actor.reparent(info.actor); + visible = true; + break; + } + + actor.visible = visible; } } + }, - switchData.inGroup.set_position(-xDest, -yDest); - switchData.inGroup.raise_top(); + _finishWorkspaceSwitch(switchData) { + this._switchData = null; - switchData.movingWindowBin.raise_top(); + for (let i = 0; i < switchData.windows.length; i++) { + let w = switchData.windows[i]; + if (w.window.is_destroyed()) // Window gone + continue; + + w.window.reparent(w.parent); + + if (w.window.get_meta_window().get_workspace() != + global.workspace_manager.get_active_workspace()) + w.window.hide(); + } + Tweener.removeTweens(switchData.container); + switchData.container.destroy(); + switchData.movingWindowBin.destroy(); + + this._movingWindow = null; + }, + + _switchWorkspace(shellwm, from, to, direction) { + if (!Main.sessionMode.hasWorkspaces || !this._shouldAnimate()) { + shellwm.completed_switch_workspace(); + return; + } - Tweener.addTween(switchData.outGroup, + let [xDest, yDest] = this._getPositionForDirection(direction); + + /* @direction is the direction that the "camera" moves, so the + * screen contents have to move one screen's worth in the + * opposite direction. + */ + xDest = -xDest; + yDest = -yDest; + + this._prepareWorkspaceSwitch(from, to, direction); + + Tweener.addTween(this._switchData.container, { x: xDest, y: yDest, time: WINDOW_ANIMATION_TIME, @@ -1799,39 +1877,10 @@ var WindowManager = new Lang.Class({ onCompleteScope: this, onCompleteParams: [shellwm] }); - Tweener.addTween(switchData.inGroup, - { x: 0, - y: 0, - time: WINDOW_ANIMATION_TIME, - transition: 'easeOutQuad' - }); }, _switchWorkspaceDone(shellwm) { - let switchData = this._switchData; - if (!switchData) - return; - this._switchData = null; - - for (let i = 0; i < switchData.windows.length; i++) { - let w = switchData.windows[i]; - if (w.window.is_destroyed()) // Window gone - continue; - if (w.window.get_parent() == switchData.outGroup) { - w.window.reparent(w.parent); - w.window.hide(); - } else - w.window.reparent(w.parent); - } - Tweener.removeTweens(switchData.inGroup); - Tweener.removeTweens(switchData.outGroup); - switchData.inGroup.destroy(); - switchData.outGroup.destroy(); - switchData.movingWindowBin.destroy(); - - if (this._movingWindow) - this._movingWindow = null; - + this._finishWorkspaceSwitch(this._switchData); shellwm.completed_switch_workspace(); },